<script setup lang="ts">
import { ref, onMounted, watch, defineProps, nextTick, onUnmounted, defineExpose, onBeforeUnmount } from "vue";
import {
  LineModelConfig,
  LocateSetData
} from "@/utils/appCommon/appCommonOptions/aeLocateConfigModel";
import * as PIXI from "pixi.js";

// 定义接收的props
const props = defineProps<{
  locateSetting: LocateSetData;
  renderParams: {
    width: number;
    height: number;
    viewMode: number;
  };
  searchParams: any;
}>();

// PIXI相关引用
let app: PIXI.Application | null = null;
let container: PIXI.Container | null = null;
const padding = 50; // 内边距50px
const yAxisFixedHeight = 20; // y轴固定高度20px
const tickCount = 10; // x轴默认标记10个刻度

// 存储图形元素
const objects = ref<Array<{
  x: number;
  y: number;
  type: 'sensor' | 'point';
  graphic: PIXI.DisplayObject;
  label?: PIXI.Text;
  tooltip?: PIXI.Container;
  id?: number
}>>([]);

// 传感器编号计数器
let sensorCounter = 1;

// 计算画布信息
const calculateCanvasInfo = () => {
  const availableWidthPixels = props.renderParams.width - 2 * padding;
  const centerY = props.renderParams.height / 2;

  // 获取线性配置
  //@ts-ignore
  const modelConfig: LineModelConfig = props.locateSetting?.config?.modelConfig || { sensorCount: 5, xRange: 100 };
  const physicalXRange = modelConfig?.xRange || 100; // 默认100mm

  const res = {
    availableWidthPixels,
    centerY,
    physicalXRange,
    scaleFactor: availableWidthPixels / physicalXRange // 物理尺寸到像素尺寸的缩放因子
  };
  return res;
};

// 初始化PIXI应用
const initPIXI = () => {
  console.log("初始化线性定位2D视图");
  if (app) {
    app.destroy(true);
  }

  // 获取目标DOM元素
  const targetElement = document.querySelector('.linear-locate-2d');
  if (!targetElement) {
    console.error("目标元素未找到");
    return;
  }

  // 清空目标元素
  targetElement.innerHTML = '';

  // 创建PIXI应用
  app = new PIXI.Application({
    width: props.renderParams.width,
    height: props.renderParams.height,
    backgroundColor: 0xffffff,
    antialias: true
  });

  // 手动将canvas添加到目标元素
  targetElement.appendChild(app.view);

  // 创建主容器
  container = new PIXI.Container();
  app.stage.addChild(container);

  // 重置传感器编号计数器
  sensorCounter = 1;

  // 绘制坐标轴和刻度
  drawAxisAndTicks();

  // 添加初始示例传感器和点
  addInitialObjects();
};

// 绘制坐标轴和刻度
const drawAxisAndTicks = () => {
  if (!app || !container) return;

  // 清空容器
  container.removeChildren();

  const { availableWidthPixels, centerY, physicalXRange } = calculateCanvasInfo();

  // 使用padding作为起始坐标
  const startX = padding;

  // 绘制背景
  const bgGraphics = new PIXI.Graphics();
  bgGraphics.beginFill(0xf5f7fa, 1);
  bgGraphics.drawRect(0, 0, props.renderParams.width, props.renderParams.height);
  bgGraphics.endFill();
  container.addChild(bgGraphics);

  // 绘制X轴
  const axisGraphics = new PIXI.Graphics();
  axisGraphics.lineStyle(2, 0x000000);
  axisGraphics.moveTo(startX, centerY);
  axisGraphics.lineTo(startX + availableWidthPixels, centerY);

  // 绘制箭头
  axisGraphics.moveTo(startX + availableWidthPixels, centerY);
  axisGraphics.lineTo(startX + availableWidthPixels - 10, centerY - 5);
  axisGraphics.moveTo(startX + availableWidthPixels, centerY);
  axisGraphics.lineTo(startX + availableWidthPixels - 10, centerY + 5);

  container.addChild(axisGraphics);

  // 绘制刻度和标签
  for (let i = 0; i <= tickCount; i++) {
    const x = startX + (i / tickCount) * availableWidthPixels;

    // 绘制刻度线
    axisGraphics.lineStyle(1, 0x000000);
    axisGraphics.moveTo(x, centerY - 5);
    axisGraphics.lineTo(x, centerY + 5);

    // 偶数位显示刻度值
    if (i % 2 === 0) {
      const physicalX = (i / tickCount) * physicalXRange;
      const displayValue = Math.round(physicalX * 10) / 10; // 保留一位小数
      const text = new PIXI.Text(displayValue.toString(), {
        fontSize: 10,
        fill: 0x333333
      });
      text.x = x - text.width / 2;
      text.y = centerY + 10;
      container.addChild(text);
    }
  }

  // 添加X轴标签
  const xLabel = new PIXI.Text('长度 (mm)', {
    fontSize: 12,
    fill: 0x333333,
    fontWeight: 'bold'
  });
  xLabel.x = startX + availableWidthPixels / 2 - xLabel.width / 2;
  xLabel.y = centerY + 30;
  container.addChild(xLabel);

  // 重新添加已有的物体和点
  redrawObjects();

  // 确保应用渲染
  if (app) {
    app.renderer.render(app.stage);
  }
};

// 重新绘制所有传感器和点
const redrawObjects = () => {
  if (!container) return;

  // 创建新的物体数组，避免重复添加
  const objectsToRedraw = [...objects.value];
  objects.value = [];

  // 重置计数器，保留原有编号
  sensorCounter = 1;

  // 先找出最大编号，确保后续添加的传感器编号连续
  const maxSensorId = objectsToRedraw
    .filter(obj => obj.type === 'sensor' && obj.id)
    .reduce((max, obj) => Math.max(max, obj.id || 0), 0);

  if (maxSensorId > 0) {
    sensorCounter = maxSensorId + 1;
  }

  // 重新添加所有物体
  objectsToRedraw.forEach(obj => {
    if (obj.type === 'sensor') {
      addSensor(obj.x, obj.y, obj.id);
    } else {
      addPoint(obj.x, obj.y);
    }
  });
};

// 坐标转换：物理坐标到画布像素坐标
const physicalToCanvas = (physicalX: number, physicalY: number) => {
  const { scaleFactor, centerY } = calculateCanvasInfo();

  const startX = padding;

  // X坐标：使用物理X值乘以缩放因子
  const canvasX = startX + physicalX * scaleFactor;
  // Y坐标：固定在线上（centerY）
  const canvasY = centerY;

  return { x: canvasX, y: canvasY };
};

// 添加传感器/点到画布
const addObjectToCanvas = (physicalX: number, physicalY: number, type: 'sensor' | 'point', id?: number) => {
  if (!container || !app) return null;

  const { x: canvasX, y: canvasY } = physicalToCanvas(physicalX, physicalY);
  const graphic = new PIXI.Graphics();
  let label: PIXI.Text | undefined;
  let tooltip: PIXI.Container | undefined;

  if (type === 'sensor') {
    // 蓝色小方块
    graphic.beginFill(0x1E90FF);
    graphic.drawRect(-5, -5, 10, 10);
    graphic.endFill();

    // 为传感器添加编号标签
    label = new PIXI.Text(id?.toString() || '', {
      fontSize: 12,
      fill: 0x000000,
      fontWeight: 'bold'
    });
    label.x = canvasX + 8; // 标签显示在物体右侧
    label.y = canvasY - 6; // 垂直居中对齐
    container.addChild(label);

    // 创建tooltip容器
    tooltip = new PIXI.Container();
    tooltip.visible = false;

    // 添加tooltip背景
    const tooltipBg = new PIXI.Graphics();
    tooltipBg.beginFill(0x000000, 0.8);
    tooltipBg.drawRoundedRect(0, 0, 120, 40, 5);
    tooltipBg.endFill();
    tooltip.addChild(tooltipBg);

    // 添加tooltip文本
    const tooltipText = new PIXI.Text(`传感器 ${id}\nX: ${physicalX.toFixed(2)}mm`, {
      fontSize: 9,
      fill: 0xffffff
    });
    tooltipText.x = 10;
    tooltipText.y = 5;
    tooltip.addChild(tooltipText);

    tooltip.x = canvasX + 15;
    tooltip.y = canvasY - 30;
    container.addChild(tooltip);

    // 设置交互属性
    graphic.interactive = true;
    graphic.buttonMode = true;

    // 添加鼠标悬浮事件
    graphic.on('mouseover', () => {
      if (tooltip) {
        tooltip.visible = true;
        app?.renderer.render(app.stage);
      }
    });

    graphic.on('mouseout', () => {
      if (tooltip) {
        tooltip.visible = false;
        app?.renderer.render(app.stage);
      }
    });
  } else {
    // 红色小圆点
    graphic.beginFill(0xFF3333);
    graphic.drawCircle(0, 0, 3);
    graphic.endFill();
  }

  graphic.x = canvasX;
  graphic.y = canvasY;
  container.addChild(graphic);

  // 确保应用渲染
  app.renderer.render(app.stage);

  return { graphic, label, tooltip };
};

// 添加传感器（蓝色方块）
const addSensor = (physicalX: number, physicalY: number, existingId?: number) => {
  const existingIndex = objects.value.findIndex(
    obj => Math.abs(obj.x - physicalX) < 0.1 && obj.type === 'sensor'
  );

  if (existingIndex === -1) {
    const currentId = existingId || sensorCounter++;
    const result = addObjectToCanvas(physicalX, physicalY, 'sensor', currentId);
    if (result && result.graphic) {
      objects.value.push({
        x: physicalX,
        y: physicalY,
        type: 'sensor',
        graphic: result.graphic,
        label: result.label,
        tooltip: result.tooltip,
        id: currentId
      });
    }
    return currentId;
  }
  return -1;
};

// 添加点（红色圆点）
const addPoint = (physicalX: number, physicalY: number) => {
  const existingIndex = objects.value.findIndex(
    obj => Math.abs(obj.x - physicalX) < 0.1 && obj.type === 'point'
  );

  if (existingIndex === -1) {
    const graphic = addObjectToCanvas(physicalX, physicalY, 'point');
    if (graphic) {
      objects.value.push({ x: physicalX, y: physicalY, type: 'point', graphic });
      return true;
    }
  }
  return false;
};

// 移除传感器或点
const removeObject = (physicalX: number, physicalY: number, type?: 'sensor' | 'point') => {
  const indicesToRemove: number[] = [];

  objects.value.forEach((obj, index) => {
    if (Math.abs(obj.x - physicalX) < 0.1 && (!type || obj.type === type)) {
      // 移除鼠标事件监听
      if (obj.graphic) {
        obj.graphic.removeAllListeners();
        if (container) {
          container.removeChild(obj.graphic);
        }
      }
      // 移除标签
      if (obj.label && container) {
        container.removeChild(obj.label);
      }
      // 移除tooltip
      if (obj.tooltip && container) {
        container.removeChild(obj.tooltip);
      }
      indicesToRemove.push(index);
    }
  });

  // 从后往前移除，避免索引变化问题
  indicesToRemove.sort((a, b) => b - a).forEach(index => {
    objects.value.splice(index, 1);
  });

  // 重新渲染
  if (app) {
    app.renderer.render(app.stage);
  }

  return indicesToRemove.length > 0;
};

// 添加初始示例传感器和点
const addInitialObjects = () => {
  // 获取线性配置
  //@ts-ignore
  const modelConfig: LineModelConfig = props.locateSetting?.config?.modelConfig || { sensorCount: 5, xRange: 100 };
  const physicalXRange = modelConfig?.xRange || 100;

  // 添加一些示例传感器（在线上均匀分布）
  addSensor(physicalXRange * 0.1, 0);
  addSensor(physicalXRange * 0.3, 0);
  addSensor(physicalXRange * 0.6, 0);
  addSensor(physicalXRange * 0.8, 0);

  // 添加一些示例点
  addPoint(physicalXRange * 0.2, 0);
  addPoint(physicalXRange * 0.5, 0);
  addPoint(physicalXRange * 0.7, 0);
};

// 暴露方法给父组件
defineExpose({
  addSensor,
  addPoint,
  removeObject
});

// 监听参数变化
watch(() => props.locateSetting, (newVal) => {
  console.log('LinearLocate2D - 定位配置变化:', newVal);
  // 当配置变化时，重新初始化PIXI
  nextTick(() => {
    initPIXI();
  });
}, { deep: true, immediate: true });

// 监听渲染参数变化，重新初始化PIXI
watch(() => props.renderParams, (newVal) => {
  console.log('LinearLocate2D - 渲染参数变化:', newVal);
  nextTick(() => {
    initPIXI();
  });
}, { deep: true, immediate: true });

watch(() => props.searchParams, (newVal) => {
  console.log('LinearLocate2D - 搜索参数变化:', newVal);
  // 2D视图对searchParams变化的处理逻辑
}, { deep: true, immediate: true });

// 清理资源和事件监听器
const cleanup = () => {
  if (app) {
    // 移除所有物体的事件监听
    objects.value.forEach(obj => {
      if (obj.graphic) {
        // 安全地移除事件监听器，避免方法不存在的错误
        if (typeof obj.graphic.removeAllListeners === 'function') {
          obj.graphic.removeAllListeners();
        }
      }
    });

    // 停止ticker
    if (app.ticker) {
      app.ticker.stop();
    }

    // 销毁应用
    app.destroy(true);
    app = null;
    container = null;
    objects.value = [];
  }
};

onMounted(() => {
  console.log('LinearLocate2D组件已挂载');
  nextTick(() => {
    initPIXI();
  });
});

// 使用onBeforeUnmount确保在组件销毁前清理资源
onBeforeUnmount(() => {
  console.log('LinearLocate2D组件即将卸载，清理资源');
  cleanup();
});

onUnmounted(() => {
  console.log('LinearLocate2D组件已卸载');
});
</script>

<template>
  <div class="linear-container" :style="{ width: renderParams.width + 'px', height: renderParams.height + 'px' }">
    <div class="linear-locate-2d"></div>
  </div>
</template>

<style scoped lang="scss">
.linear-container {
  position: relative;
  background-color: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.linear-locate-2d {
  width: 100%;
  height: 100%;
  background-color: #ffffff;
  overflow: hidden;
  position: relative;
}

.linear-locate-2d canvas {
  display: block;
}
</style>
